
using namespace std;

typedef double A;   // 被类型参数 A 隐藏
template <typename A, typename B> void f(A a, B b)
{
    A tmp = a;      // tmp 的类型为模板参数 A 的类型，而非 double
    // double B;    // 错误：重声明模板参数 B
}

// 错误：非法重用模板参数名 V
// template <typename V, typename V>

// 声明中的模板参数的名字不必与定义中相同（以下都是相同的函数模板）
template <typename T> T calc(const T&, const T&); // 声明
template <typename U> U calc(const U&, const U&); // 声明
template <typename Type> Type calc(const Type&, const Type&) { /* ... */ } // 定义

// typename T::value_type 显式地告诉编译器 value_type 是一个类型（不是 static 数据成员）
template <typename T> typename T::value_type top(const T& c)
{
    if (!c.empty())
        return c.back();
    else
        return typename T::value_type();
}
